TCPDF版本:v6.6.2
雖然我還滿確定這是 bug 的,也發了 PR,但他們還沒有確認。
故以下內容先當作是我個人的看法。
TrueType 字型中 head 表中有個 checksumAdjustment 欄位,這扮演 checksum 的角色。
如果開啟 subset 功能,TCPDF 必須重組字型資料。當它在寫入這個欄位的時候,位置的計算忘記加上一個額外的 offset,導致這個 checksum 會被寫入到字型的其它位置,造成不可預知的結果。
個人覺得這就是有些字型可以正常運作,但有些字型會遇到異常狀況的原因。由於原始字型內部 table 的排列順序不同,被覆蓋掉的資料如果是不重要的欄位,可能看起來就很正常。
檔案:src/include/tcpdf_fonts.php
1374 ~ 1368 行
$offset = ($numTables * 16);
foreach ($table as $tag => $data) {
$font .= $tag; // tag
$font .= pack('N', $data['checkSum']); // checkSum
// 注意下面這行是有加上 $offset 的
$font .= pack('N', ($data['offset'] + $offset)); // offset
$font .= pack('N', $data['length']); // length
}
foreach ($table as $data) {
$font .= $data['data'];
}
// set checkSumAdjustment on head table
$checkSumAdjustment = 0xB1B0AFBA - self::_getTTFtableChecksum($font, strlen($font));
// 下面這行計算偏移量時,忘記把 $offset 加上去
$font = substr($font, 0, $table['head']['offset'] + 8).pack('N', $checkSumAdjustment).substr($font, $table['head']['offset'] + 12);
第一個 foreach 迴圈,是在寫 TableRecord。其中 offset 的部分它是有加上 $offset
的
$font .= pack('N', ($data['offset'] + $offset)); // offset
但後來在寫入 $checkSumAdjustment
時,卻忘記加上去了
要修正的話把 $offset
加上去即可
$font = substr($font, 0, $table['head']['offset'] + $offset + 8).pack('N', $checkSumAdjustment).substr($font, $table['head']['offset'] + $offset + 12);